#ifdef UTIL_PLATFORM_WIN32
#include "lang/System.h"
#include "io/InputStream.h"
#include "io/OutputStream.h"
#include "io/PrintStream.h"
#include "util/MemoryFIFOBuffer.hpp"
#include <windows.h>
using namespace yzrilyzr_io;
using namespace yzrilyzr_util;
using namespace yzrilyzr_array;
namespace yzrilyzr_lang{
	ECLASS(WinConsoleOutputStream, public OutputStream){
	private:
	HANDLE hConsole;
	MemoryFIFOBuffer<int8_t> buffer;
	public:
	WinConsoleOutputStream(){
		SetConsoleOutputCP(CP_UTF8);
		SetConsoleCP(CP_UTF8);
		hConsole=GetStdHandle(STD_OUTPUT_HANDLE);
	}
	void write(int32_t b)override{
		buffer.write(b);
	}
	void write(const ByteArray & array, u_index off, u_index len)override{
		buffer.write(array, off, len);
	}
	void flush()override{
		DWORD charsWritten;
		auto array=buffer.toArray();
		buffer.reset();
		WriteConsoleA(hConsole, array._array, array.length, &charsWritten, NULL);
	}
	};
	ECLASS(WinConsoleInputStream, public InputStream){
	private:
	HANDLE hConsole;
	MemoryFIFOBuffer<int8_t> buffer;
	public:
	WinConsoleInputStream(){
		SetConsoleCP(CP_UTF8);
		hConsole=GetStdHandle(STD_INPUT_HANDLE);
	}
	~WinConsoleInputStream(){}
	void readConsoleToBuffer(){
		DWORD charsRead;
		wchar_t c[1024];
		buffer.compact();
		if(ReadConsoleW(hConsole, c, 1024, &charsRead, NULL)){
			String str(c, 0, charsRead);
			buffer.write(str.getBytes(UTF8));
		}
	}
	int32_t read() override{
		if(buffer.available() == 0){
			readConsoleToBuffer();
		}
		if(buffer.available() > 0){
			int8_t buf;
			buffer.read(buf);
			return buf & 0xff;
		}
		return -1;
	}
	u_index read(ByteArray & b, u_index off, u_index len) override{
		Util::checkRange(len, off, off + len);
		if(buffer.available() == 0){
			readConsoleToBuffer();
		}
		if(buffer.available() > 0){
			return buffer.read(b, off, len);
		}
		return -1;
	}
	u_index available() override{
		u_index bufAv=buffer.available();
		if(bufAv > 0)return bufAv;
		DWORD eventsAvailable;
		if(GetNumberOfConsoleInputEvents(hConsole, &eventsAvailable) && eventsAvailable > 0){
			// 检查是否有实际的字符输入事件
			INPUT_RECORD inputRecord;
			DWORD eventsRead;
			if(PeekConsoleInput(hConsole, &inputRecord, 1, &eventsRead) && eventsRead > 0){
				if(inputRecord.EventType == KEY_EVENT &&
				   inputRecord.Event.KeyEvent.bKeyDown &&
				   inputRecord.Event.KeyEvent.uChar.UnicodeChar != 0){
					return 1; // 有有效字符输入
				}
			}
		}
		return 0;
	}
	void close() override{}
	};
	yzrilyzr_io::InputStream & System::createInputStream(){
		static WinConsoleInputStream * ins=new WinConsoleInputStream();
		return *ins;
	}
	yzrilyzr_io::OutputStream & System::createOutStream(){
		static WinConsoleOutputStream * ins=new WinConsoleOutputStream();
		return *ins;
	}
}
#endif // UTIL_PLATFORM_WIN32